import http from './http'
import { apiMsgProp } from '@/utils/global'
import type { CourseItem, UserGrade, Grade, CourseCreateItem, ImportMemberResult } from '@/types/course'
import moment from 'moment'
import type { Pagination } from '@/types/global'
import type { UserInfo } from '@/types/user'

const CourseService = {
    /**
     * @function list 获取课程列表
     * @param pagination 分页
     * @param category_id 分类id
     * @param keyword 搜索关键字
     * @returns CourseItem[] 课程列表
     */
    list: async ({ page, limit }: Pagination, category_id?: number, keyword?: string): Promise<{ items: CourseItem[]; pagination: Pagination }> => {
        let apiStr: string = `/course/info/list?current_page=${page}&per_page=${limit}`
        if (category_id) apiStr += `&category_id=${category_id}`
        if (keyword) apiStr += `&keyword=${keyword}`
        const res = await http.get(apiStr)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const items = res.data.data.items
        return {
            items,
            pagination: res.data.data.pagination,
        }
    },
    /**
     * @function listToPersonal 获取课程列表(个人)
     * @returns CourseItem[] 课程列表
     */
    listToPersonal: async (): Promise<CourseItem[]> => {
        const res = await http.get('/course/user/courseList?per_page=10000')
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const items = res.data.data.items.sort((a: CourseItem, b: CourseItem) => a.sort_order - b.sort_order)
        return items
    },

    /**
     * @function listToPersonal 获取课程列表(个人)
     * @returns CourseItem[] 课程列表
     */
    getUserCourseList: async (searchForm: {
        page?: number
        limit?: number
    }): Promise<CourseItem[]> => {
        const res = await http.get('/course/user/courseList?current_page=' + searchForm.page + '&per_page=' + searchForm.limit)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const items = res.data.data.items.sort((a: CourseItem, b: CourseItem) => a.sort_order - b.sort_order)
        return {
            dataList: items,
            pagination: {
                page: res.data.data.pagination.current_page,
                limit: res.data.data.pagination.per_page,
                total: res.data.data.pagination.total,
            },
        }
    },
    /**
     * @function getById 获取课程信息
     * @param id 课程id
     * @returns CourseItem 课程信息
     */
    getById: async (id: number): Promise<CourseItem> => {
        const res = await http.get(`/course/info/${id}/info`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.items
    },
    /**
     * @function update 编辑课程信息
     * @param data 课程信息
     */
    update: async (data: CourseCreateItem): Promise<void> => {
        const _data: any = { ...data }
        _data.start_date = moment(_data.start_date).format('YYYY-MM-DD HH:mm:ss')
        _data.end_date = moment(_data.end_date).format('YYYY-MM-DD HH:mm:ss')
        _data.report_deadline = moment(_data.report_deadline).format('YYYY-MM-DD HH:mm:ss')
        const res = await http.post(`/course/info/${data.id}/update`, _data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    /**
     * @function create 编辑课程信息
     * @param data 课程信息
     */
    create: async (data: CourseCreateItem): Promise<CourseItem> => {
        const _data: any = { ...data }
        _data.start_date = moment(_data.start_date).format('YYYY-MM-DD HH:mm:ss')
        _data.end_date = moment(_data.end_date).format('YYYY-MM-DD HH:mm:ss')
        _data.report_deadline = moment(_data.report_deadline).format('YYYY-MM-DD HH:mm:ss')
        const res = await http.post(`/course/info/add`, _data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)

        return res.data.data.items
    },
    /**
     * @function delete 删除课程
     * @param ids 课程id列表
     */
    delete: async (ids: number[]): Promise<void> => {
        const res = await http.delete(`/course/info/batch`, { data: { ids } })
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    /**
     * @function gradeToStudent 获取课程学习情况(成绩) / 个人
     * @param course_id 课程id
     * @param student_id 学生id
     * @returns UserGrade 学生成绩信息
     */
    gradeToStudent: async (course_id: number, student_id: number): Promise<UserGrade> => {
        const res = await http.post('/course/info/studyDetail', { course_id, student_id })
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const rawData = res.data.data.items

        // 解构接口数据, 删掉学生信息~
        const data = { ...rawData }
        delete data.student_id
        delete data.student_name
        delete data.statistics

        // 声明成绩列表
        const gradeList: Grade[] = []
        for (const key in data) {
            if (Object.prototype.hasOwnProperty.call(data, key)) {
                const item = data[key]
                item.forEach((ele: any) => {
                    const { title, actual_score, total_score, unit_id, quiz_id, video_id, reflection_id } = ele
                    let resourceId = 0
                    switch (key) {
                        case 'quiz':
                            resourceId = quiz_id
                            break
                        case 'video':
                            resourceId = video_id
                            break
                        case 'reflection':
                            resourceId = reflection_id
                            break
                    }
                    gradeList.push({
                        itemName: title,
                        itemType: key,
                        grade: actual_score,
                        range: `0-${total_score}`,
                        percentage: `${((parseFloat(actual_score) / parseFloat(total_score)) * 100).toFixed(2)}%`,
                        contributiontocoursetotal: actual_score,
                        unit_id,
                        id: resourceId,
                    })
                })
            }
        }
        // 课程总分
        gradeList.push({
            itemName: '課程總分',
            itemType: 'total',
            grade: rawData.statistics.actual_score,
            range: `0-${rawData.statistics.total_score}`,
            percentage: `${((parseFloat(rawData.statistics.actual_score) / parseFloat(rawData.statistics.total_score)) * 100).toFixed(2)}%`,
            contributiontocoursetotal: rawData.statistics.actual_score,
            unit_id: 0,
            id: 0,
        })

        return {
            gradeList,
            student_id: rawData.student_id,
            student_name: rawData.student_name,
        }
    },
    /**
     * @function gradesToStudent 获取课程学习情况(成绩) / 全部
     * @param course_id 课程id
     * @returns UserGrade[] 学生成绩信息列表
     */
    gradesToStudent: async (course_id: number): Promise<UserGrade[]> => {
        const res = await http.post('/course/info/studyDetail', { course_id })
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const list: UserGrade[] = []
        res.data.data.items.forEach((rawData: any) => {
            // 解构接口数据, 删掉学生信息~
            const data = { ...rawData }
            delete data.student_id
            delete data.student_name
            delete data.statistics

            // 声明成绩列表
            const gradeList: Grade[] = []
            for (const key in data) {
                if (Object.prototype.hasOwnProperty.call(data, key)) {
                    const item = data[key]
                    item.forEach((ele: any) => {
                        const { title, actual_score, total_score, unit_id, quiz_id, video_id, reflection_id } = ele
                        let resourceId = 0
                        switch (key) {
                            case 'quiz':
                                resourceId = quiz_id
                                break
                            case 'video':
                                resourceId = video_id
                                break
                            case 'reflection':
                                resourceId = reflection_id
                                break
                        }
                        gradeList.push({
                            itemName: title,
                            itemType: key,
                            grade: actual_score,
                            range: `0-${total_score}`,
                            percentage: `${((parseFloat(actual_score) / parseFloat(total_score)) * 100).toFixed(2)}%`,
                            contributiontocoursetotal: actual_score,
                            unit_id,
                            id: resourceId,
                        })
                    })
                }
            }
            // 课程总分
            gradeList.push({
                itemName: '課程總分',
                itemType: 'total',
                grade: rawData.statistics.actual_score,
                range: `0-${rawData.statistics.total_score}`,
                percentage: `${((parseFloat(rawData.statistics.actual_score) / parseFloat(rawData.statistics.total_score)) * 100).toFixed(2)}%`,
                contributiontocoursetotal: rawData.statistics.actual_score,
                unit_id: 0,
                id: 0,
            })

            list.push({
                gradeList,
                student_id: rawData.student_id,
                student_name: rawData.student_name,
            })
        })

        return list
    },
    // 導出評分者報告
    exportInfoAllStudyDetail: async (params: any): Promise<any> => {
        const res = await http.post('/course/info/allStudyDetail', params)
        if (res.status !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data
    },
    /**
     * @function gradesToTeacher 获取評分者報告
     * @param course_id 课程id
     * @param form 查询参数
     * @returns any 評分者報告
     */
    gradesToTeacher: async (course_id: number, form: any): Promise<any> => {
        const res = await http.post('/course/info/allStudyDetail', { course_id, ...form })
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }

        const rawData = res.data.data.items
        const tableData = rawData.map((student: any) => {
            const unitScores: any = {}

            // 合并所有评分项
            const data = { ...student }
            delete data.student_id
            delete data.student_name
            delete data.statistics
            delete data.overall
            const allItems: Grade[] = []
            for (const key in data) {
                if (Object.prototype.hasOwnProperty.call(data, key)) {
                    const item = data[key]
                    item.forEach((ele: any) => {
                        const { title, actual_score, total_score, unit_id, quiz_id, video_id, reflection_id } = ele
                        let resourceId = 0
                        switch (key) {
                            case 'quiz':
                                resourceId = quiz_id
                                break
                            case 'video':
                                resourceId = video_id
                                break
                            case 'reflection':
                                resourceId = reflection_id
                                break
                        }
                        allItems.push({
                            itemType: key,
                            id: resourceId,
                            itemName: title,
                            grade: actual_score,
                            range: `0-${total_score}`,
                            percentage: `${((parseFloat(actual_score) / parseFloat(total_score)) * 100).toFixed(2)}%`,
                            contributiontocoursetotal: actual_score,
                            unit_id,
                        })
                    })
                }
            }

            // 按unit_id分组计算总分
            allItems.forEach(item => {
                const unitKey = item.itemName
                unitScores[unitKey] = { ...item }
            })

            return {
                student_name: student.student_name || 'grade.report.grader.index.table_label_1',
                ...unitScores,
            }
        })

        const columns = [{ prop: 'student_name', label: 'grade.report.grader.index.table_label_2', width: 120, type: 'student_name', id: 0, unit_id: 0 }]
        for (const key in tableData[0]) {
            if (Object.prototype.hasOwnProperty.call(tableData[0], key)) {
                if (key === 'student_name') continue
                columns.push({
                    prop: key,
                    label: key,
                    width: 120,
                    type: tableData[0][key].itemType,
                    id: tableData[0][key].id,
                    unit_id: tableData[0][key].unit_id,
                })
            }
        }

        return { columns, tableData }
    },
    /**
     * @function members 获取用户列表(课程成员)
     * @param role_id 角色id
     * @param course_id 课程 id
     * @param key 关键字
     * @returns UserInfo[] 用户列表
     */
    members: async (role_id: number, course_id: number, key?: string): Promise<UserInfo[]> => {
        let urlStr = `course/user/getUnbindCourseUser?role_id=${role_id}&course_id=${course_id}`
        if (key) urlStr += `&keyword=${key}`
        const res = await http.get(urlStr)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.items
    },
    /**
     * @function addMember 添加课程成员
     * @param courseId 课程id
     * @param data 成员信息
     * @returns
     */
    addMember: async (courseId: number, data: { userIds: string; role_id: number | null; code: string }): Promise<void> => {
        const res = await http.post(`/course/info/bindUser/${courseId}`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    /**
     * @function delMember 删除课程成员
     * @param courseId 课程id
     * @param userIds 用户id组
     * @returns
     */
    delMember: async (courseId: number, userIds: number[]): Promise<void> => {
        const res = await http.post(`/course/info/unbindUser/${courseId}`, { userIds: userIds.join(',') })
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    /**
     * @function upMember 更新课程成员
     * @param id 用户id
     * @param role_id 角色id
     * @param code 学号
     * @returns
     */
    upMember: async (id: string, role_id: number | null, code: string): Promise<void> => {
        const res = await http.post(`/course/user/update`, { id, role_id, code })
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    /**
     * @function importMember 批量导入课程成员
     * @param courseId 课程id
     * @param file 文件
     * @returns
     */
    importMember: async (data: FormData): Promise<ImportMemberResult> => {
        const res = await http.post(`/course/info/bindUsers`, data, {
            headers: {
                'Content-Type': 'multipart/form-data',
            },
            timeout: undefined,
        })
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)

        return res.data.data.items
    },

    /**
     * @function 复制课程
     * @param id 课程id
     * @returns CourseItem 课程信息
     */
    copyClass: async (id: number): Promise<void> => {
        const res = await http.get(`/course/info/${id}/copy`)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },



    // 获取未读消息列表
    getNoticesUnreadList: async (): Promise<void> => {
        const res = await http.get(`/course/notices/unread?per_page=100&page=1`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.list
    },
    // 获取全部消息列表
    getNoticesList: async (searchData): Promise<void> => {
        const res = await http.get(`/course/notices?per_page=${searchData.limit}&page=${searchData.page}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return {
            dataList: res.data.data.list,
            pagination: {
                page: res.data.data.pagination.page,
                limit: res.data.data.pagination.size,
                total: res.data.data.pagination.total
            }
        }
    },
    // 获取消息详情
    getNoticesDetail: async (id: number): Promise<void> => {
        const res = await http.get(`/course/notices/${id}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data
    },
    // 获取未读消息数量
    getNoticesUnreadCount: async (): Promise<void> => {
        const res = await http.get(`/course/notices/unread-count`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.count
    },
    // 标记为已读
    putNoticesRead: async (id: number): Promise<void> => {
        const res = await http.put(`/course/notices/${id}/read`)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    // 删除通知
    deleteNotices: async (id: number): Promise<void> => {
        const res = await http.delete(`/course/notices/${id}`)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },

    // 获取留言列表
    getMessageList: async (searchData:any): Promise<void> => {
        const res = await http.get(`/course/message/my?course_id=${searchData.id}&current_page=${searchData.page}&per_page=${searchData.limit}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return {
            dataList: res.data.data.items,
            pagination: {
                page: res.data.data.pagination.current_page,
                limit: res.data.data.pagination.per_page,
                total: res.data.data.pagination.total
            }
        }
    },
    // 获取未读留言数量
    getMessageUnreadCount: async (id:number): Promise<void> => {
        const res = await http.get(`/course/message/unread-count?course_id=${id}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.items.count
    },
    // 發送留言/回復留言
    postMessage: async (data:any): Promise<void> => {
        const res = await http.post(`/course/message`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
        return res.data
    },
    // 标记留言为已读
    postMessageRead: async (id: number): Promise<void> => {
        const res = await http.post(`/course/message/${id}/read`)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    


    // new 发送沟通
    postCommunication: async (data:any): Promise<void> => {
        const res = await http.post(`/course/communication`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
        return res.data
    },
    // new 查看未读数量
    getCommunicationUnreadCount: async (): Promise<void> => {
        const res = await http.get(`/course/communication/unread-count`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data.unread_count
    },
    // new 查看与指定用户沟通记录
    getCommunicationConversation: async (searchData:any): Promise<void> => {
        let getUrl = '';
        if(searchData.page == undefined){
            getUrl = `/course/communication/conversation?other_user_id=${searchData.id}&per_page=${searchData.limit}`
        }else{
            getUrl = `/course/communication/conversation?other_user_id=${searchData.id}&current_page=${searchData.page}&per_page=${searchData.limit}`
        }
        const res = await http.get(getUrl)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return {
            dataList: res.data.data.items,
            pagination: {
                page: res.data.data.current_page,
                limit: res.data.data.per_page,
                total: res.data.data.total,
                totalPages: res.data.data.last_page,
            }
        }
    },
    // new 标记为已读
    postCommunicationMarkAsRead: async (data): Promise<void> => {
        const res = await http.post(`/course/communication/mark-as-read`, data)
        // apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    // new 获取最近联系人列表
    getCommunicationHistory: async (searchData:any): Promise<void> => {
        const res = await http.get(`/course/communication/history?current_page=${searchData.page}&per_page=${searchData.limit}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return {
            dataList: res.data.data.items,
            pagination: {
                page: res.data.data.current_page,
                limit: res.data.data.per_page,
                total: res.data.data.total
            }
        }
    },

    // 課程公告 || 課程討論區接口
    // 按类型获取课程公告或讨论区
    getCourseNotice: async (searchData:any): Promise<void> => {
        const res = await http.get(`/course/course-notice/course/${searchData.courseId}/type/${searchData.type}?page=${searchData.page}&per_page=${searchData.limit}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return {
            dataList: res.data.data.items,
            pagination: {
                page: res.data.data.current_page,
                limit: res.data.data.per_page,
                total: res.data.data.total
            }
        }
    },
    // 获取公告详情
    getCourseNoticeDetail: async (id: number): Promise<void> => {
        const res = await http.get(`/course/course-notice/${id}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data
    },
    // 新增课程公告
    postCourseNotice: async (data:any): Promise<void> => {
        const res = await http.post(`/course/course-notice`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
        return res.data
    },
    // 更新课程公告
    putCourseNotice: async (id: number, data: any): Promise<void> => {
        const res = await http.put(`/course/course-notice/${id}`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
        return res.data
    },
    // 删除课程公告
    deleteCourseNotice: async (id: number): Promise<void> => {
        const res = await http.delete(`/course/course-notice/${id}`)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
    },
    // 新增讨论区评论
    postCourseDiscussion: async (data:any): Promise<void> => {
        const res = await http.post(`/course/course-discussion`, data)
        apiMsgProp(res.data.code, res.data.message)
        if (res.data.code !== 200) return Promise.reject(res.data)
        return res.data
    },
    // 获取讨论列表
    getCourseDiscussion: async (id: number): Promise<void> => {
        const res = await http.get(`/course/course-discussion/notice/${id}`)
        if (res.data.code !== 200) {
            apiMsgProp(res.data.code, res.data.message)
            return Promise.reject(res.data)
        }
        return res.data.data
    },
}

export default CourseService
